/**
 * \file array-list.h
 * \brief Implementação de elementos num array
 * \description
 * A ideia é que o programador não se tenha de preocupar com o espaço em memória da estrutura!
 */
# ifndef ARRAY_LIST_DEF
# define ARRAY_LIST_DEF

# include <stdlib.h>
# include "../../io/logs/logSystem.h"
# include "../../base/types.h"

# define LIST_ALLOC_JUMP 3

typedef struct {
	void **list;
	int size;
	int elems;
} ArrayList;

/**
 * \brief Da o numero de elementos da lista
 * \param list lista
 * \return Tamanho da lista
 */
int arrayGetLength(ArrayList *list);
/**
 * \brief Vai buscar o elemento
 * \param list lista
 * \param indice Posição do elemento!
 * \return NULL se não existir ou elemento valido
 */
void * arrayGet(ArrayList *list, int indice);
/**
 * \brief Insere um elemento no fim da lista
 * \param list lista
 * \param data Novo elemento
 * \return 0 se não conseguir inserir - 1 se correr tudo ok
 */
int arrayInsert(ArrayList *list, void *data);
/**
 * \brief Insere um elemento no fim da lista
 * \param list lista
 * \param indice Posicao aonde inserir
 * \param data Novo elemento
 * \param replace 1 se pretende substituir 0 se pretende fazer shift e inserir
 * \return 0 se não conseguir inserir - 1 se correr tudo ok
 */
int arrayInsertAt(ArrayList *list, int indice, void *data, int replace);
/**
 * \brief Troca os dados das duas posições
 * \param list lista
 * \param indA Posicao do primeiro elemento
 * \param indB Posicao do segundo elemento
 * \return 1 se correr bem 0 se nao conseguir
 */
int arraySwap (ArrayList *list, int indA, int indB);
/**
 * \brief Remove elemento da posicao dada
 * \param list Lista
 * \param indice posicao
 * \return 1 se conseguir 0 se não
 */
int arrayRemoveFrom(ArrayList *list, int indice);
/**
 * \brief Remove elemento
 * \param list Lista
 * \param data Elemento a apagar
 * \param func Função que compara elementos
 */
int arrayRemove(ArrayList *list, void *data, equalFunction func);
/**
 * \brief Cria espaço em memória para esta estrutura
 * \param initialSize Tamanho inicial da lista (boa estimativa)
 * \return Estrutura
 */
ArrayList * newArrayList (int initialSize);
/**
 * \brief liberta espaço ocupado pela estrutura
 * \param list estrutura
 */
void freeArrayList (ArrayList *list);

/**
 * \brief Ve o index do elemento dado
 * \param list lista
 * \param data elemento
 * \param func função de comparação
 * \return -1 se não encontrar
 */
int arrayIndexOf (ArrayList *list, void *data, equalFunction func);

void arraySort (ArrayList *lst, equalFunction f, int desc);

# endif
